From d5f4579384fc847a6191af36fd00024731dc3388 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 8 Jan 2020 00:25:51 -0500 Subject: [PATCH] dragdest: Steps towards allowing nested drop sites --- gtk/gtkdragdest.c | 99 ++++++++++++++++++++--------------------------- 1 file changed, 43 insertions(+), 56 deletions(-) diff --git a/gtk/gtkdragdest.c b/gtk/gtkdragdest.c index 7af2f36914..26ffa3e8e2 100644 --- a/gtk/gtkdragdest.c +++ b/gtk/gtkdragdest.c @@ -514,15 +514,9 @@ gtk_drop_target_drag_motion (GtkDropTarget *dest, target = gtk_drop_target_match (dest, drop); if (actions && target) - { - gdk_drop_status (drop, dest_actions); - gtk_drop_target_set_contains (dest, TRUE); - } + gdk_drop_status (drop, dest_actions); else - { - gdk_drop_status (drop, 0); - gtk_drop_target_set_contains (dest, FALSE); - } + gdk_drop_status (drop, 0); return TRUE; } @@ -550,7 +544,6 @@ gtk_drop_target_emit_drag_leave (GtkDropTarget *dest, set_drop (dest, drop); g_signal_emit (dest, signals[DRAG_LEAVE], 0, drop, time); set_drop (dest, NULL); - gtk_drop_target_set_contains (dest, FALSE); } static gboolean @@ -561,14 +554,9 @@ gtk_drop_target_emit_drag_motion (GtkDropTarget *dest, { gboolean result = FALSE; - dest->contains_pending = TRUE; - set_drop (dest, drop); g_signal_emit (dest, signals[DRAG_MOTION], 0, drop, x, y, &result); - if (dest->contains_pending) - gtk_drop_target_set_contains (dest, result); - return result; } @@ -590,22 +578,11 @@ static void gtk_drop_target_set_contains (GtkDropTarget *dest, gboolean contains) { - GtkWidget *widget; - - widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest)); - - dest->contains_pending = FALSE; - if (dest->contains == contains) return; dest->contains = contains; - if (contains) - gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_DROP_ACTIVE, FALSE); - else - gtk_widget_unset_state_flags (widget, GTK_STATE_FLAG_DROP_ACTIVE); - g_object_notify_by_pspec (G_OBJECT (dest), properties[PROP_CONTAINS]); } @@ -639,27 +616,55 @@ clear_current_dest (gpointer data, GObject *former_object) g_object_set_data (G_OBJECT (data), "current-dest", NULL); } +static void +unset_current_dest (gpointer data) +{ + GtkDropTarget *dest = data; + GtkWidget *widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest)); + + gtk_drop_target_set_contains (dest, FALSE); + if (widget) + gtk_widget_unset_state_flags (widget, GTK_STATE_FLAG_DROP_ACTIVE); +} + static void gtk_drop_set_current_dest (GdkDrop *drop, GtkDropTarget *dest) { GtkDropTarget *old_dest; + GtkWidget *widget; old_dest = g_object_get_data (G_OBJECT (drop), "current-dest"); + if (old_dest == dest) + return; + +g_print ("set current dest %p\n", dest); if (old_dest) - g_object_weak_unref (G_OBJECT (old_dest), clear_current_dest, drop); + { + gtk_drop_target_set_contains (old_dest, FALSE); + + widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (old_dest)); + if (widget) + gtk_widget_unset_state_flags (widget, GTK_STATE_FLAG_DROP_ACTIVE); + + gtk_drop_target_emit_drag_leave (old_dest, drop); + + g_object_weak_unref (G_OBJECT (old_dest), clear_current_dest, drop); + } - g_object_set_data (G_OBJECT (drop), "current-dest", dest); + g_object_set_data_full (G_OBJECT (drop), "current-dest", dest, unset_current_dest); if (dest) - g_object_weak_ref (G_OBJECT (dest), clear_current_dest, drop); -} + { + g_object_weak_ref (G_OBJECT (dest), clear_current_dest, drop); -static GtkDropTarget * -gtk_drop_get_current_dest (GdkDrop *drop) -{ - return g_object_get_data (G_OBJECT (drop), "current-dest"); + widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest)); + if (widget) + gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_DROP_ACTIVE, FALSE); + + gtk_drop_target_set_contains (dest, TRUE); + } } static gboolean @@ -668,14 +673,12 @@ gtk_drop_target_handle_event (GtkEventController *controller, { GtkDropTarget *dest = GTK_DROP_TARGET (controller); GdkDrop *drop; - GtkDropTarget *old_dest; double x, y; gboolean found = FALSE; gdk_event_get_coords (event, &x, &y); drop = gdk_event_get_drop (event); - old_dest = gtk_drop_get_current_dest (drop); switch ((int)gdk_event_get_event_type (event)) { @@ -684,14 +687,6 @@ gtk_drop_target_handle_event (GtkEventController *controller, break; case GDK_DROP_START: - /* We send a leave before the drop so that the widget unhighlights properly. - */ - if (old_dest) - { - gtk_drop_target_emit_drag_leave (old_dest, drop); - gtk_drop_set_current_dest (drop, NULL); - } - found = gtk_drop_target_emit_drag_drop (dest, drop, x, y); break; @@ -701,12 +696,7 @@ gtk_drop_target_handle_event (GtkEventController *controller, if (found) { - if (old_dest && old_dest != dest) - { - gtk_drop_target_emit_drag_leave (old_dest, drop); - gtk_drop_set_current_dest (drop, NULL); - } - + g_print ("setting dest from event controller handle_event\n"); gtk_drop_set_current_dest (drop, dest); } @@ -721,7 +711,6 @@ void gtk_drag_dest_handle_event (GtkWidget *toplevel, GdkEvent *event) { - GtkDropTarget *dest; GdkDrop *drop; GdkEventType event_type; @@ -737,16 +726,14 @@ gtk_drag_dest_handle_event (GtkWidget *toplevel, break; case GDK_DRAG_LEAVE: - dest = gtk_drop_get_current_dest (drop); - if (dest) - { - gtk_drop_target_emit_drag_leave (dest, drop); - gtk_drop_set_current_dest (drop, NULL); - } + g_print ("setting dest from fallback handle_event for LEAVE\n"); + gtk_drop_set_current_dest (drop, NULL); break; case GDK_DRAG_MOTION: case GDK_DROP_START: + g_print ("setting dest from fallback handle_event for MOTION or START\n"); + gtk_drop_set_current_dest (drop, NULL); gdk_drop_status (drop, 0); break; -- 2.30.2